package inc.zhugastrov.ui;

import inc.zhugastrov.users.Account;
import inc.zhugastrov.users.Position;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.SwingConstants;

import org.apache.log4j.Logger;
import org.apache.log4j.xml.DOMConfigurator;

import static inc.zhugastrov.users.Account.returnEmptyAccount;
import static inc.zhugastrov.dbactions.DBActions.updateUser;
import static inc.zhugastrov.dbactions.DBActions.checkForUniqueLogin;
import static inc.zhugastrov.dbactions.DBActions.addUser;
import static inc.zhugastrov.ui.UserManagment.getModel;
import static inc.zhugastrov.dbactions.DBActions.*;

public class UserUpdateForm extends JPanel implements ActionListener {
	private  static Logger logger = Logger.getLogger(UserUpdateForm.class);
	private JTextField nameLabel;
	private JTextField surnameLabel;
	private JTextField passportNumberLabel;
	private JTextField addressLabel;
	private JTextField loginLabel;
	private JPasswordField passwordLabel1;
	private JPasswordField passwordLabel2;
	private JTextField salaryLabel;
	private JTextField positionLabel;
	private JButton editButton;
	private JButton okButton;
	private JButton cancelButton;
	private boolean wasEdited = true;
	private Account current;
	private JFrame frame;
	private ArrayList<JLabel> labels = new ArrayList<JLabel>();
	private ArrayList<JTextField> fields;
	private JComboBox combo;
	private boolean isNewAccount = false;

	private void showForm() {

		frame = new JFrame("Update user");
		frame.setResizable(false);
		frame.getContentPane().add(this);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.pack();
		frame.setSize(600, 400);
		frame.setVisible(true);
	}

	public UserUpdateForm() {
		DOMConfigurator.configure("prop.xml");
		isNewAccount = true;
		current = returnEmptyAccount();
		initComponent(current);
		showForm();
		for (JTextField field : fields) {
			field.setText("");
			field.setEditable(true);
			field.setBorder(BorderFactory.createLineBorder(Color.BLACK));

		}
		positionLabel.setVisible(false);
		combo.setVisible(true);
		editButton.setEnabled(false);
	}

	public UserUpdateForm(Account account) {
		isNewAccount = false;
		current = account;
		initComponent(current);
		passwordLabel1.setVisible(false);
		passwordLabel2.setVisible(false);
		positionLabel.setVisible(true);
		combo.setVisible(false);
		editButton.setEnabled(true);
		//getOrdersById(current.getId());
		showForm();
	}

	private void initComponent(Account account) {
		// Name
		nameLabel = new JTextField(account.getName());
		JLabel l1 = new JLabel("Name : ", SwingConstants.TRAILING);
		labels.add(l1);

		// Surname
		surnameLabel = new JTextField(account.getSurname());
		JLabel l2 = new JLabel("Surname : ", SwingConstants.TRAILING);
		labels.add(l2);

		// Passport
		passportNumberLabel = new JTextField(account.getPassportNumber()
				.toString());
		JLabel l3 = new JLabel("Passport # ", SwingConstants.TRAILING);
		labels.add(l3);

		// Address
		addressLabel = new JTextField(account.getAddress());
		JLabel l4 = new JLabel("Address : ", SwingConstants.TRAILING);
		labels.add(l4);

		// login
		loginLabel = new JTextField(account.getLogin());
		JLabel l5 = new JLabel("Login : ", SwingConstants.TRAILING);
		labels.add(l5);

		// password
		passwordLabel1 = new JPasswordField(account.getPassword());
		passwordLabel2 = new JPasswordField();
		JLabel l6 = new JLabel("Password : ", SwingConstants.TRAILING);
		JLabel l7 = new JLabel("Confirm password : ", SwingConstants.TRAILING);
		if (isNewAccount == true) {
			labels.add(l6);
			labels.add(l7);
		}

		// salary
		salaryLabel = new JTextField(account.getSalary().toString());
		JLabel l8 = new JLabel("Salary : ", SwingConstants.TRAILING);
		labels.add(l8);

		// position
		positionLabel = new JTextField(account.getPosition());
		JLabel l9 = new JLabel("Position : ", SwingConstants.TRAILING);
		labels.add(l9);

		// ok
		okButton = new JButton("Confirm");
		okButton.setLocation(280, 340);
		okButton.setSize(100, 30);
		okButton.setActionCommand("Confirm");
		okButton.addActionListener(this);
		add(okButton);

		// cancel
		cancelButton = new JButton("Cancel");
		cancelButton.setLocation(480, 340);
		cancelButton.setSize(100, 30);
		cancelButton.setActionCommand("Cancel");
		cancelButton.addActionListener(this);
		add(cancelButton);
		// Edit
		editButton = new JButton("Edit");
		editButton.setLocation(380, 340);
		editButton.setSize(100, 30);
		editButton.setActionCommand("Edit");
		editButton.addActionListener(this);
		add(editButton);
		combo = new JComboBox();
		combo.addItem(Position.ACCOUNTANT);
		combo.addItem(Position.MANAGER);
		combo.addItem(Position.SELLER);

		fields = new ArrayList<JTextField>() {
			{

				add(nameLabel);
				add(surnameLabel);
				add(passportNumberLabel);
				add(addressLabel);
				add(loginLabel);
				if (isNewAccount == true) {
					add(passwordLabel1);
					add(passwordLabel2);
				}
				add(salaryLabel);
				add(positionLabel);
			}
		};
		int i = 15;
		for (JTextField field : fields) {
			add(field);
			field.setSize(100, 20);
			field.setEditable(false);
			field.setBorder(BorderFactory.createEmptyBorder());
			field.setLocation(450, i);
			i += 30;

		}
		combo.setFocusable(false);
		combo.setLocation(positionLabel.getLocation());
		combo.setSize(positionLabel.getSize());
		combo.setVisible(false);
		add(combo);
		i = 15;
		for (JLabel label : labels) {
			add(label);
			label.setSize(70, 20);
			label.setLocation(380, i);
			i += 30;

		}
		setLayout(new BorderLayout());

	}

	@Override
	public void actionPerformed(ActionEvent e) {
		if (e.getActionCommand().equals("Confirm"))
			if (!wasEdited)
				cancel();
			else
				confirm();
		else if (e.getActionCommand().equals("Cancel"))
			cancel();
		else
			edit();

	}

	private void edit() {

		for (JTextField field : fields) {
			field.setEditable(true);
			field.setBorder(BorderFactory.createLineBorder(Color.BLACK));
		}
		positionLabel.setVisible(false);
		combo.setVisible(true);
	}

	private Account getAcc() {
		if (isValidationRulesPassed()) {
			Account newAcc = new Account();
			newAcc.setName(nameLabel.getText());
			newAcc.setSurname(surnameLabel.getText());
			newAcc.setAddress(addressLabel.getText());
			newAcc.setLogin(loginLabel.getText());
			newAcc.setPassword(String.valueOf(passwordLabel1.getPassword()));
			newAcc.setPassportNumber(passportNumberLabel.getText());
			newAcc.setSalary(Double.valueOf(salaryLabel.getText()));
			newAcc.setPosition(combo.getSelectedItem().toString());
			return newAcc;
		} else
			return null;

	}

	private void confirm() {
		Account tmp = getAcc();
		if ((isNewAccount == false) && (getAcc() != null)) {
			tmp.setId(current.getId());
			updateUser(tmp);
		} else {
			addUser(tmp);
			tmp.setId(getIdForNewItem(tmp.getLogin()));
			logger.info("User "+AuthorizationForm.getAuthorizedUser().getName()+" add account with id " + tmp.getId());
			getModel().addRow(tmp);
		}
		JOptionPane.showMessageDialog(frame, "Done", "Info",
				JOptionPane.INFORMATION_MESSAGE);
		frame.dispose();

	}

	private void cancel() {
		Object[] options = { "Yes", "No" };
		int n = JOptionPane.showOptionDialog(frame, "Are you sure?",
				"Canceletion", JOptionPane.YES_NO_OPTION,
				JOptionPane.QUESTION_MESSAGE, null, // do
													// not
													// use
													// a
													// custom
													// Icon
				options, // the titles of buttons
				options[0]); // default button title
		if (n == JOptionPane.YES_OPTION)
			frame.dispose();
	}

	private Boolean isValidationRulesPassed() {
		positionLabel.setText(combo.getSelectedItem().toString());
		for (JTextField field : fields) {
			if (field.getText().equals("")) {
				JOptionPane.showMessageDialog(this,
						"One or more of fields are empty", "Error",
						JOptionPane.ERROR_MESSAGE);
				return false;
			} else if (field.getText().length() > 200) {
				JOptionPane
						.showMessageDialog(
								this,
								"One or more of fields are too long max is 200 characters",
								"Error", JOptionPane.ERROR_MESSAGE);
				return false;
			}

		}
		if ((isNewAccount == true)
				&& (!checkForUniqueLogin(loginLabel.getText()))) {
			JOptionPane.showMessageDialog(this, "That login already contains",
					"Error", JOptionPane.ERROR_MESSAGE);
			return false;
		}
		Pattern pattern = Pattern.compile("[^a-zA-Z]");
		Matcher matcher = pattern.matcher(nameLabel.getText());
		if (matcher.find()) {
			JOptionPane.showMessageDialog(this,
					"Field 'Name' didn't pass validation. "
							+ "Allows only letters, no digits, no white "
							+ "spaces or other shit", "Error",
					JOptionPane.ERROR_MESSAGE);
			return false;
		}
		matcher = pattern.matcher(surnameLabel.getText());
		if (matcher.find()) {
			JOptionPane.showMessageDialog(this,
					"Field 'Surname' didn't pass validation. "
							+ "Allows only letters, no digits, no white "
							+ "spaces or other shit", "Error",
					JOptionPane.ERROR_MESSAGE);
			return false;
		}
		matcher = pattern.matcher(surnameLabel.getText());
		if (matcher.find()) {
			JOptionPane.showMessageDialog(this,
					"Field 'Surname' didn't pass validation. "
							+ "Allows only letters, no digits, no white "
							+ "spaces or other shit", "Error",
					JOptionPane.ERROR_MESSAGE);
			return false;
		}
		pattern = Pattern.compile("\\W");
		matcher = pattern.matcher(passportNumberLabel.getText());
		if (matcher.find()) {
			JOptionPane.showMessageDialog(this,
					"Field 'Passport' didn't pass validation. "
							+ "Allows only word character, " + "no other shit",
					"Error", JOptionPane.ERROR_MESSAGE);
			return false;
		}
		try {
			Double check = Double.valueOf(salaryLabel.getText());
			if (check <= 0)
				throw new Exception();
		} catch (Exception e) {
			JOptionPane.showMessageDialog(this,
					"Field 'Salary' didn't pass validation. "
							+ "Allows only double, " + "no other shit",
					"Error", JOptionPane.ERROR_MESSAGE);
			return false;
		}
		if (!validatePassword(passwordLabel1.getPassword(),
				passwordLabel2.getPassword())
				&& (isNewAccount == true)) {
			JOptionPane.showMessageDialog(this, "Passwords missmatch. "
					+ "Try again", "Error", JOptionPane.ERROR_MESSAGE);
			return false;
		}

		return true;
	}

	private boolean validatePassword(char[] first, char[] second) {
		if (first.length != second.length)
			return false;
		for (int i = 0; i < first.length; i++) {
			if (first[i] != second[i])
				return false;
		}
		return true;
	}

}
